/**
*
Java Diagram Package; An extremely flexible and fast multipurpose diagram
component for Swing.
Copyright (C) 2001 Eric Crahen <crahen@cse.buffalo.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package diagram.tool;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.SwingUtilities;
import diagram.Diagram;
import diagram.DiagramUI;
import diagram.Figure;
import diagram.SelectionModel;
/**
* @class SelectionTool
*
* @date 08-20-2001
* @author Eric Crahen
* @version 1.0
*
* This tool allows a the selected figures in a Diagram to be modified.
*
* - Left mouse button selects an item.
* - Shift clicking edits the current selection.
* - Left clicking no where unselects the current selection.
*
*/
public class SelectionTool extends AbstractTool {
private Figure[] figures = new Figure[4];
private MouseHandler mouseHandler = new MouseHandler();
/**
* Install support for something in the given Diagram
*
* @param Diagram
*/
public void install(Diagram diagram) {
diagram.addMouseListener(mouseHandler);
}
/**
* Remove support for something that was previously installed.
*
* @param Diagram
*/
public void uninstall(Diagram diagram) {
diagram.removeMouseListener(mouseHandler);
}
/**
*
*/
protected class MouseHandler extends MouseAdapter {
/**
* When an unconsumed left mouse click has been detected update the
* components SelectionModel.
*
* @param MouseEvent
*/
public void mouseClicked(MouseEvent e) {
// Check for left mouse button & a valid selection
if(e.isConsumed() || !SwingUtilities.isLeftMouseButton(e) || e.getClickCount() > 1)
return;
// Find the node which was clicked on
Diagram diagram = (Diagram)e.getSource();
Figure node = (Figure)diagram.findFigure(e.getPoint());
SelectionModel selectionModel = diagram.getSelectionModel();
// If a node was shift-clicked, update it
if(e.isShiftDown() && node != null) {
if(selectionModel.contains(node))
selectionModel.remove(node);
else
selectionModel.add(node);
// Repaint the diagram
DiagramUI ui = (DiagramUI)diagram.getUI();
ui.refreshFigure(node);
// If not shift-clicked, start by clearing the current selection
} else if(!e.isShiftDown())
deselectAll(diagram, selectionModel, node);
}
/**
* When an unconsumed left mouse click has been detected update the
* components SelectionModel.
*
* This event is not consumed, so it will get passed on to other
* support objects. This makes mouse motions like 1 click & drag seem
* more natural.
*
* @param MouseEvent
*/
public void mousePressed(MouseEvent e) {
// Check for left mouse button , no shift & a valid selection
if(e.isConsumed() || e.isShiftDown() || !SwingUtilities.isLeftMouseButton(e) ||
e.getClickCount() > 1)
return;
// Find the node which was clicked on
Diagram diagram = (Diagram)e.getSource();
Figure node = (Figure)diagram.findFigure(e.getPoint());
SelectionModel selectionModel = diagram.getSelectionModel();
// If the model has 1 item or less selected, add this item quickly
if(selectionModel.size() <= 1 && node != null)
deselectAll(diagram, selectionModel, node);
}
} /* MouseHandler */
/**
* Deselect all items but the given Figure (if any)
*
* @param SelectionModel
* @param Figure
*/
private final void deselectAll(Diagram diagram, SelectionModel model, Figure except) {
// Copy previously selected items
Figure[] items = (Figure[])model.toArray((Object[])figures);
DiagramUI ui = (DiagramUI)diagram.getUI();
// Remove nodes that just were un-selected, but not the one
// node still clicked on
for(int i=0; i<items.length && items[i] != null; i++) {
Figure node = items[i];
// Damage the area & remove
if(except == null || node != except) {
ui.damageFigure(node);
model.remove(node);
}
}
// If a node was click and it was not selected, select it.
if(except != null && !model.contains(except)) {
// Damage & remove
ui.damageFigure(except);
model.add(except);
}
// Refresh an item, to force a repaint when the fast refresh is not enabled
if(items.length > 0 && items[0] != null)
ui.refreshFigure(items[0]);
else if(except != null)
ui.refreshFigure(except);
java.util.Arrays.fill(items, 0, items.length, null);
}
}